package dancrawler.server;

import java.util.ArrayList;
import java.util.Iterator;

/**
 *
 */
public class AI {

    private ArrayList<Creature> bots = new ArrayList<>();
    private ArrayList<Creature> ibots = new ArrayList<>();
    private GameHandler gh;

    public AI(GameHandler gh) {
        this.gh = gh;
    }

    public void registerBot(Creature cr) {
        cr.setStrength(1+cr.getLevel()/2);
        cr.setMaxHp(10+10*cr.getLevel()/4);
        cr.setDef(1+cr.getLevel()/4);
        bots.add(cr);
    }
    public void setInactive(Gameworld gw)
    {
        for(Creature cr : bots)
        {
            if(cr.getWorld() == gw)
            {
                ibots.add(cr);
                bots.remove(cr);
            }
        }
    }
    public void setActive(Gameworld gw)
    {
        for(Creature cr : ibots)
        {
            if(cr.getWorld() == gw)
            {
                bots.add(cr);
                ibots.remove(cr);
            }
        }
    }

    public void think() {
        Iterator<Creature> it = bots.iterator();
        while (it.hasNext()) {
            Creature cr = it.next();
            if (cr.isDead()) {
                it.remove();
            } else {
                int range = cr.getPerception();
                int crange = 1, cx, cy, cnum = 8, cs = 3;
                while (crange <= range) {
                    cx = cr.getX() - crange;
                    cy = cr.getY() - crange;
                    do {
                        if(analyseTile(cr, cr.getWorld().getTile(cx, cy)))
                        {
                            return;
                        }
                        if (cy == cr.getY() - crange) {
                            if (cx == cr.getX() + crange) {
                                cy++;
                            } else {
                                cx++;
                            }
                        } else if (cx == cr.getX() + crange) {
                            if (cy == cr.getY() + crange) {
                                cx--;
                            } else {
                                cy++;
                            }
                        }
                        else if (cy == cr.getY() + crange) {
                            if (cx == cr.getX() - crange) {
                                cy--;
                            } else {
                                cx--;
                            }
                        }
                        else
                        {
                            cy--;
                        }
                    } while (cx != cr.getX() - crange || cy != cr.getY() - crange);

                    cs += 2;
                    cnum += 8;
                    crange++;
                }

            }
        }
    }
    private boolean analyseTile(Creature cr, Tile tile)
    {
        if(tile == null || cr == null)
        {
            return false;
        }
        for(GameObject go:tile.getContents())
        {
            if(go instanceof PlayerChar)
            {
                PlayerChar pc = (PlayerChar)go;
                if(cr.attack(pc))
                {
                    return true;
                }
                if(cr.move(getDirection(cr.getX(),cr.getY(), pc.getX(), pc.getY())))
                {
                    return true;
                }
            }
        }
        return false;
    }
    private int getDirection(int x1, int y1, int x2, int y2)
    {
        if(x1 == x2)
        {
            if(y1 > y2)
            {
                return Gameworld.NORTH;
            }
            else
            {
                return Gameworld.SOUTH;
            }
        }
        else if(y1 == y2)
        {
            if(x1 > x2)
            {
                return Gameworld.WEST;
            }
            else
            {
                return Gameworld.EAST;
            }
        }
        else if(y1 < y2 && x1 < x2)
        {
            return 3;
        }
        else if(y1 < y2 && x1 > x2)
        {
            return 1;
        }
        else if(y1 > y2 && x1 < x2)
        {
            return 9;
        }
        else
        {
            return 7;
        }
    }
}
